package com.hzy.pms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.hzy.cms.domain.OssInfo;
import com.hzy.pms.domain.Brand;
import com.hzy.pms.domain.ProductCategory;
import com.hzy.pms.domain.Sku;
import com.hzy.pms.mapper.BrandMapper;
import com.hzy.pms.mapper.ProductCategoryMapper;
import com.hzy.pms.mapper.SkuMapper;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import com.hzy.pms.domain.bo.ProductBo;
import com.hzy.pms.domain.vo.ProductVo;
import com.hzy.pms.domain.Product;
import com.hzy.pms.mapper.ProductMapper;
import com.hzy.pms.service.IProductService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 商品信息Service业务层处理
 *
 * @author zengxin
 * @date 2023-10-17
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class ProductServiceImpl implements IProductService {

    private final ProductMapper baseMapper;

    private final SkuMapper skuMapper;

    private final BrandMapper brandMapper;

    private final ProductCategoryMapper productCategoryMapper;

    /**
     * 查询商品信息
     */
    @Override
    public ProductVo queryById(Long id){
        ProductVo productVo = baseMapper.selectVoById(id);
        LambdaQueryWrapper<Sku> qw = new LambdaQueryWrapper<>();
        qw.eq(Sku::getProductId, id);
        productVo.setSkuList(skuMapper.selectVoList(qw));
        return productVo;
    }

    /**
     * 查询商品信息列表
     */
    @Override
    public TableDataInfo<ProductVo> queryPageList(ProductBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<Product> lqw = buildQueryWrapper(bo);
        Page<ProductVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询商品信息列表
     */
    @Override
    public List<ProductVo> queryList(ProductBo bo) {
        LambdaQueryWrapper<Product> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<Product> buildQueryWrapper(ProductBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<Product> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getProductSnapshotId() != null, Product::getProductSnapshotId, bo.getProductSnapshotId());
        lqw.eq(bo.getBrandId() != null, Product::getBrandId, bo.getBrandId());
        lqw.eq(bo.getCategoryId() != null && !bo.getCategoryId().equals(0L), Product::getCategoryId, bo.getCategoryId());
        lqw.eq(StringUtils.isNotBlank(bo.getOutProductId()), Product::getOutProductId, bo.getOutProductId());
        lqw.like(StringUtils.isNotBlank(bo.getName()), Product::getName, bo.getName());
        lqw.eq(bo.getPublishStatus() != null, Product::getPublishStatus, bo.getPublishStatus());
        lqw.eq(bo.getSort() != null, Product::getSort, bo.getSort());
        lqw.eq(bo.getPrice() != null, Product::getPrice, bo.getPrice());
        lqw.eq(StringUtils.isNotBlank(bo.getUnit()), Product::getUnit, bo.getUnit());
        lqw.eq(bo.getWeight() != null, Product::getWeight, bo.getWeight());
        lqw.eq(StringUtils.isNotBlank(bo.getDetailHtml()), Product::getDetailHtml, bo.getDetailHtml());
        lqw.eq(StringUtils.isNotBlank(bo.getDetailMobileHtml()), Product::getDetailMobileHtml, bo.getDetailMobileHtml());
        lqw.like(StringUtils.isNotBlank(bo.getBrandName()), Product::getBrandName, bo.getBrandName());
        lqw.like(StringUtils.isNotBlank(bo.getProductCategoryName()), Product::getProductCategoryName, bo.getProductCategoryName());
        lqw.eq(StringUtils.isNotBlank(bo.getProductAttr()), Product::getProductAttr, bo.getProductAttr());
        lqw.orderByDesc(Product::getUpdateTime);
        return lqw;
    }

    /**
     * 新增商品信息
     */
    @Override
    @Transactional
    public Boolean insertByBo(ProductBo bo) {
        Product add = BeanUtil.toBean(bo, Product.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
            if (!CollectionUtil.isEmpty(bo.getSkuList())) {
                List<Sku> skuList = bo.getSkuList().stream().map(item -> BeanUtil.toBean(item, Sku.class)).collect(Collectors.toList());
                skuList.forEach(item -> {
                    item.setProductId(bo.getId());
                });
                skuMapper.insertBatch(skuList);
            }
        }
        return flag;
    }

    /**
     * 修改商品信息
     */
    @Override
    @Transactional
    public Boolean updateByBo(ProductBo bo) {
        Product update = BeanUtil.toBean(bo, Product.class);
        validEntityBeforeSave(update);
        List<Long> idList = bo.getSkuList().stream().filter(it -> it.getId() != null).map(it -> it.getId()).collect(Collectors.toList());
        Map<String,Object> map = new HashMap<>();
        map.put("product_id", update.getId());
        Map<Long, Sku> skuMap = skuMapper.selectByMap(map).stream().collect(Collectors.toMap(it -> it.getId(), it -> it));
        //针对已有的进行编辑
        List<Sku> updateList = bo.getSkuList().stream()
                .filter(it -> it.getId() != null)
                .map(item -> BeanUtil.toBean(item, Sku.class))
                .collect(Collectors.toList());
        if (!CollectionUtil.isEmpty(updateList)) {
            log.info("共有{}个sku需要修改，{}，productId：{}",updateList.size(), JSONUtil.toJsonStr(updateList),bo.getId());
            updateList.forEach(it->{
                Sku sku = skuMap.get(it.getId());
                sku.setPrice(it.getPrice());
                sku.setSpData(it.getSpData());
                sku.setPic(it.getPic());
                sku.setOutSkuId(it.getOutSkuId());
                sku.setStock(it.getStock());
            });
            skuMapper.updateBatchById(updateList);
        }
        //针对没有的进行新增
        List<Sku> addList = bo.getSkuList().stream()
                .filter(it -> it.getId() == null)
                .map(item -> BeanUtil.toBean(item, Sku.class))
                .collect(Collectors.toList());
        if (!CollectionUtil.isEmpty(addList)) {
            log.info("共有{}个sku需要新增，{}，productId：{}",addList.size(), JSONUtil.toJsonStr(addList),bo.getId());
            addList.forEach(sku -> {
                sku.setProductId(bo.getId());
                skuMapper.insert(sku);
            });
            skuMapper.updateBatchById(addList);
        }
        //删除
        List<Long> deleteIds = skuMap.keySet().stream().filter(it -> !idList.contains(it)).collect(Collectors.toList());
        if (!CollectionUtil.isEmpty(deleteIds)) {
            log.info("共有{}个sku需要删除，{}，productId：{}",deleteIds.size(), JSONUtil.toJsonStr(deleteIds),bo.getId());
            skuMapper.deleteBatchIds(deleteIds);
        }
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(Product entity){
        if (entity.getId() != null) {
            Product dbProduct = baseMapper.selectById(entity.getId());
            Assert.notNull(dbProduct, "查询数据无效！");
        }


        Brand brand = brandMapper.selectById(entity.getBrandId());
        Assert.notNull(brand, "查询品牌数据无效！");
        entity.setBrandName(brand.getName());

        ProductCategory productCategory = productCategoryMapper.selectById(entity.getCategoryId());
        Assert.notNull(productCategory, "查询商品分类数据无效！");
        entity.setProductCategoryName(productCategory.getName());
//        List<String> ids = StrUtil.split(entity.getProductCategoryName(), ",");
//        Assert.isTrue(!CollectionUtil.isEmpty(ids), "查询商品分类数据无效！");
//        List<String> productCategoryNames = productCategoryMapper.selectBatchIds(ids).stream().map(item -> item.getName()).collect(Collectors.toList());
//        entity.setProductCategoryName(StrUtil.join("/", productCategoryNames));
    }

    /**
     * 批量删除商品信息
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            LambdaQueryWrapper<Sku> qw = new LambdaQueryWrapper<>();
            qw.in(Sku::getProductId, ids);
            Assert.isTrue(!skuMapper.exists(qw), "库存信息未删除！");
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }


    @Override
    public IPage<ProductVo> queryWebPageList(ProductBo bo, Pageable pageQuery) {
        MPJLambdaWrapper<Product> lqw = buildMPJLambdaWrapper(bo);
        return baseMapper.selectVoPage(new Page<>(pageQuery.getPageNumber(), pageQuery.getPageSize()), lqw);
    }

    private MPJLambdaWrapper<Product> buildMPJLambdaWrapper(ProductBo bo) {
        Map<String, Object> params = bo.getParams();
        MPJLambdaWrapper lqw = new MPJLambdaWrapper<Product>()
                .select(Product::getId, Product::getName, Product::getPrice)
                .select(OssInfo::getUrl)
                .selectAs(OssInfo::getUrl, Product::getPic)
                .leftJoin(OssInfo.class, OssInfo::getOssId, Product::getPic)
                .eq(bo.getProductSnapshotId() != null, Product::getProductSnapshotId, bo.getProductSnapshotId())
                .orderByDesc(Product::getUpdateTime);
        return lqw;
    }

}
